/*
 * Copyright (C), 2002-2015, 鑻忓畞鏄撹喘鐢靛瓙鍟嗗姟鏈夐檺鍏徃
 * FileName: Coder.java
 * Author:   14111222
 * Date:     2015-1-14 涓婂崍10:26:16
 * Description: //妯″潡鐩殑銆佸姛鑳芥弿杩�     
 * History: //淇敼璁板綍
 * <author>      <time>      <version>    <desc>
 * 淇敼浜哄鍚�            淇敼鏃堕棿            鐗堟湰鍙�                 鎻忚堪
 */
package com.sso.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 *   鍔犲瘑杈呭姪绫�br> 
 *          鍔犲瘑util  BASE64 SHA MD5 HMAC
 *
 * @author 14111222
 * @see [鐩稿叧绫�鏂规硶]锛堝彲閫夛級
 * @since [浜у搧/妯″潡鐗堟湰] 锛堝彲閫夛級
 */
@SuppressWarnings("restriction")
public class EncryptUtil {
    
    private static final String  SHA = "SHA-1";
            
    private static final String  MD5 = "MD5";
    
    /**
     * 
     * 鍔熻兘鎻忚堪: BASE64 鍔犲瘑
     *  BASE64 鍔犲瘑
     *
     * @param key
     * @return
     * @see [鐩稿叧绫�鏂规硶](鍙�)
     * @since [浜у搧/妯″潡鐗堟湰](鍙�)
     */
    public static byte[] decryptBASE64(String key)  {
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bt = null;
        try {
            bt = decoder.decodeBuffer(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bt;
    }
    
    /**
     * 
     * 鍔熻兘鎻忚堪: BASE64 瑙ｅ瘑
     *  BASE64 瑙ｅ瘑
     *
     * @param key
     * @return
     * @throws IOException
     * @see [鐩稿叧绫�鏂规硶](鍙�)
     * @since [浜у搧/妯″潡鐗堟湰](鍙�)
     */
    public static String encryptBASE64(byte[] key) {
        return (new BASE64Encoder()).encodeBuffer(key);
    }
    
    /**
     * 
     * 鍔熻兘鎻忚堪: MD5 鍔犲瘑 榛樿32 浣�
     *  MD5 鍔犲瘑
     *
     * @param inputText
     * @return
     * @see [鐩稿叧绫�鏂规硶](鍙�)
     * @since [浜у搧/妯″潡鐗堟湰](鍙�)
     */
    public static String encryptMD5(String inputText) {  
        byte[] s = null;
        try {
            MessageDigest m = MessageDigest.getInstance(MD5);  
            m.update(inputText.getBytes("UTF8"));  
            s = m.digest();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }  
        /**
         * 鍙傝� apache commons-codec-1.9.jar鐨�org.apache.commons.codec.binary.Hex
         */
        return new String(encodeHex(s));
    }  
    
    /**
     * 
     * 鍔熻兘鎻忚堪: MD5鍔犲瘑_16浣嶅姞瀵�
     *      MD5鍔犲瘑_16浣嶅姞瀵�
     *
     * @param mdString
     * @return
     * @see [鐩稿叧绫�鏂规硶](鍙�)
     * @since [浜у搧/妯″潡鐗堟湰](鍙�)
     */
    public  String encryptMD5_16bits(String key) {
        return encryptMD5(key).substring(8, 24);
    }
    
    /**
     * 鍙傝� apache commons-codec-1.9.jar鐨�org.apache.commons.codec.binary.Hex
     */
    private static final char[] DIGITS = {
        '0', '1', '2', '3', '4', '5', '6', '7',
           '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    };
    /**
     * 鍙傝� apache commons-codec-1.9.jar鐨�org.apache.commons.codec.binary.Hex
     */
    public static char[] encodeHex(byte[] data) {
        int l = data.length;
           char[] out = new char[l << 1];
           for (int i = 0, j = 0; i < l; i++) {
               out[j++] = DIGITS[(0xF0 & data[i]) >>> 4 ];
               out[j++] = DIGITS[ 0x0F & data[i] ];
           }
           return out;
    }
    
    /**
     * 
     * 鍔熻兘鎻忚堪: SHA-1 鍔犲瘑
     *      SHA-1 鍔犲瘑
     *
     * @param key
     * @return
     * @see [鐩稿叧绫�鏂规硶](鍙�)
     * @since [浜у搧/妯″潡鐗堟湰](鍙�)
     */
    public static String encryptSHA(String key) {
        byte[] bt = null;
        try {
            MessageDigest md = MessageDigest.getInstance(SHA);
            md.update(key.getBytes("utf-8"));
            bt = md.digest();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new String(encodeHex(bt));
    }
    
    /**
     * 
     * 鍔熻兘鎻忚堪: hmac鍔犲瘑
     *      hmac鍔犲瘑
     * @param data 鍔犲瘑鏁版嵁
     * @param algorithm 鍩轰簬閭ｇ鍔犲瘑绫诲瀷 杩涜hmac
     * @param key 绉橀挜
     * @return 
     * @see [鐩稿叧绫�鏂规硶](鍙�)
     * @since [浜у搧/妯″潡鐗堟湰](鍙�)
     */
    public static String encryptHMAC(byte[] data, String  algorithm, byte[] key) {
        Mac mac = null;
        try {
            SecretKey secretKey = new SecretKeySpec(key, algorithm);
            mac = Mac.getInstance(algorithm);
            mac.init(secretKey);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return new String(encodeHex(mac.doFinal(data)));
    }
    
    /*    private static String hex(byte[] arr) {  
                StringBuffer sb = new StringBuffer();  
                    for (int i = 0; i < arr.length; ++i) {  
                        *//**
                         * Integer.toHexString(杞负16杩涘埗) Integer.toOctalString()杞负8杩涘埗
                         * 姝ゅarr[i] & 0xFF 杩愮畻缁撴灉涓轰竴涓猧nt锛屼笉鑳界洿鎺ュ皢灏哸rr[i] Integer.toHexString銆俠yte涓嶈兘鐩存帴杞负int
                         *                      reason: byte 8bits, int 32bits.  灏哹yte杞负int鐨勬椂鍊�闇�灏嗛珮24涓烘竻绌�
                         *                      arr[i] & 0xFF  寰楀埌 a[i]鐨�ASCII鐮侊紝 | 0x100
                         *//*
                        sb.append(Integer.toHexString((arr[i] & 0xFF) | 0x100).substring(1,  
                                3));  
                    }  
                return sb.toString();  
            }  */
    
    public static void main(String[] args) {
        try {
            System.out.println(encryptBASE64("鏉ㄦ捣 宄�b".getBytes("UTF-8")));
            System.out.println(new String(decryptBASE64(encryptBASE64("鏉ㄦ捣 宄�b".getBytes("UTF-8")))));
            System.out.println(encryptMD5("鏉ㄦ捣 宄�b"));
            System.out.println(encryptSHA("鏉ㄦ捣宄�b"));
            System.out.println(encryptHMAC("the data string".getBytes("UTF-8"), "HmacMD5", "绉橀挜".getBytes("UTF-8")).toUpperCase());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
